package fr.inserm.u674.chcdbweb.model.files;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import fr.inserm.u674.chcdbweb.model.DTO.Tissue;

/**
 * 
 * @author Thomas Burguiere
 * 
 */
public class GridFileSaver {
	private ArrayList<Tissue> tissueList;
	private boolean showTissueQuantities;
	private HashMap<String, String> eavVariables;

	@SuppressWarnings("unused")
	private GridFileSaver() {
	}

	public GridFileSaver(ArrayList<Tissue> tissueList, HashMap<String, String> eavVariables) {
		this.tissueList = tissueList;
		this.eavVariables = eavVariables;
		this.showTissueQuantities = true;
	}

	public GridFileSaver(ArrayList<Tissue> tissueList, HashMap<String, String> eavVariables,
		boolean showTissueQuantities) {
		this.tissueList = tissueList;
		this.eavVariables = eavVariables;
		this.showTissueQuantities = showTissueQuantities;
	}

	public ArrayList<Tissue> getTissueList() {
		return tissueList;
	}

	public void setTissueList(ArrayList<Tissue> tissueList) {
		this.tissueList = tissueList;
	}

	public HashMap<String, String> getEavVariables() {
		return eavVariables;
	}

	public void setEavVariables(HashMap<String, String> eavVariables) {
		this.eavVariables = eavVariables;
	}

	public boolean isShowTissueQuantities() {
		return showTissueQuantities;
	}

	public void setShowTissueQuantities(boolean showTissueQuantities) {
		this.showTissueQuantities = showTissueQuantities;
	}

	public File saveAsCSV(File directory) throws IOException, InvalidFormatException {
		File csvFile = null;

		if (directory != null)
			csvFile = File.createTempFile("Grid", ".csv", directory);
		else
			csvFile = File.createTempFile("Grid", ".csv");
		FileOutputStream csvOutputStream = new FileOutputStream(csvFile);

		StringBuffer buff = new StringBuffer();
		// HEADER ROW
		buff.append("CHCID,ID,Type,\"Master CHCID\"");

		for (String eavVarName : eavVariables.keySet()) {
			String varName = eavVariables.get(eavVarName);
			if (varName.indexOf(",") != -1)
				varName = "\"" + varName + "\"";
			buff.append(varName + ",");
		}
		if (showTissueQuantities)
			buff.append("\"Tissue Quantities\",");

		//deleting trailing comma
		buff.deleteCharAt(buff.length() - 1);
		// newLine
		buff.append("\r\n");

		// SECOND HEADER ROW (FULL VARIABLE NAMES)
		for (String eavVarName : eavVariables.keySet()) {
			if (eavVarName.indexOf(",") != -1)
				eavVarName = "\"" + eavVarName + "\"";

			buff.append(eavVarName + ",");
		}
		
		//deleting trailing comma
		buff.deleteCharAt(buff.length() - 1);
		// newLine
		buff.append("\r\n");

		// OTHER ROWS
		for (Tissue tissue : tissueList) {
			buff.append(tissue.toString() + ",");
			buff.append(tissue.getChcID() + ",");
			buff.append(tissue.getTissueTypeID() + ",");
			if (!tissue.isMasterTissue()) {
				buff.append(tissue.getMasterTissue().toString() + ",");
			}
			else {
				buff.append("--------,");
			}

			for (String eavVarName : eavVariables.keySet()) {
				String modality = "";
				if (tissue.getEavData().get(eavVarName) != null
					&& tissue.getEavData().get(eavVarName).getModality() != null)
					modality = tissue.getEavData().get(eavVarName).getModality();
				else
					modality = "";

				if (modality.indexOf(",") != -1)
					modality = "\"" + modality + "\"";
				buff.append(modality + ",");
			}

			if (this.showTissueQuantities) {
				buff.append(tissue.getQuantityLeft() != null ? tissue.getQuantityLeft()
					: "").append(",");
			}
			buff.deleteCharAt(buff.length() - 1);// removes the trailing comma

			// newLine
			buff.append("\r\n");

			csvOutputStream.write(buff.toString().getBytes(Charset.forName("UTF-8")));
			buff.setLength(0);
		}

		return csvFile;
	}

	public File saveAsTabTxt(File directory) throws IOException, InvalidFormatException {
		File tabFile = null;

		if (directory != null)
			tabFile = File.createTempFile("Grid", ".txt", directory);
		else
			tabFile = File.createTempFile("Grid", ".txt");
		FileOutputStream csvOutputStream = new FileOutputStream(tabFile);

		StringBuffer buff = new StringBuffer();
		// HEADER ROW
		buff.append("CHCID\tID\tType\t\"Master CHCID\"");

		for (String eavVarName : eavVariables.keySet()) {
			String varName = eavVariables.get(eavVarName);

			buff.append(varName + "\t");
		}
		if (showTissueQuantities)
			buff.append("Tissue Quantities\t");

		//deleting trailing \t
		buff.deleteCharAt(buff.length() - 1);
		// newLine
		buff.append("\r\n");

		// SECOND HEADER ROW (FULL VARIABLE NAMES)
		for (String eavVarName : eavVariables.keySet()) {

			buff.append(eavVarName + "\t");
		}
		
		//deleting trailing \t
		buff.deleteCharAt(buff.length() - 1);
		// newLine
		buff.append("\r\n");

		// OTHER ROWS
		for (Tissue tissue : tissueList) {
			buff.append(tissue.toString() + "\t");
			buff.append(tissue.getChcID() + "\t");
			buff.append(tissue.getTissueTypeID() + "\t");
			if (!tissue.isMasterTissue())
				buff.append(tissue.getMasterTissue().toString() + "\t");
			else
				buff.append("--------\t");

			for (String eavVarName : eavVariables.keySet()) {
				String modality = "";
				if (tissue.getEavData().get(eavVarName) != null
					&& tissue.getEavData().get(eavVarName).getModality() != null)
					modality = tissue.getEavData().get(eavVarName).getModality();
				else
					modality = "";

				buff.append(modality + "\t");
			}

			if (this.showTissueQuantities) {
				buff.append(tissue.getQuantityLeft() != null ? tissue.getQuantityLeft()
					: "").append("\t");
			}
			buff.deleteCharAt(buff.length() - 1);// removes the trailing tab

			// newLine
			buff.append("\r\n");

			csvOutputStream.write(buff.toString().getBytes(Charset.forName("UTF-8")));
			buff.setLength(0);
		}

		return tabFile;
	}

	public File saveAsXLS(File directory) throws IOException, InvalidFormatException {

		File excelFile = null;
		if (directory != null)
			excelFile = File.createTempFile("Grid", ".xls", directory);
		else
			excelFile = File.createTempFile("Grid", ".xls");

		// Workbook wb = WorkbookFactory.create(new FileInputStream(excelFile));
		Workbook wb = new HSSFWorkbook();
		Sheet sheet = wb.createSheet();

		Row row = null;
		Cell cell = null;

		// HEADER ROW
		row = sheet.createRow(0);
		cell = row.createCell(0);
		cell.setCellValue("CHCID");
		cell = row.createCell(1);
		cell.setCellValue("ID");
		cell = row.createCell(2);
		cell.setCellValue("Type");
		cell = row.createCell(3);
		cell.setCellValue("Master CHCID");

		int i = 4;
		for (String eavVarName : eavVariables.keySet()) {
			cell = row.createCell(i);
			cell.setCellValue(eavVariables.get(eavVarName));
			i++;
		}

		if (this.showTissueQuantities) {
			cell = row.createCell(i);
			cell.setCellValue("Tissue Quantities");
		}

		// SECOND HEADER ROW (FULL VARIABLE NAMES)
		row = sheet.createRow(1);

		i = 4;
		for (String eavVarName : eavVariables.keySet()) {
			cell = row.createCell(i);
			cell.setCellValue(eavVarName);
			i++;
		}

		// OTHER ROWS
		int n = 2;
		for (Tissue tissue : tissueList) {
			row = sheet.createRow(n);
			cell = row.createCell(0);
			cell.setCellValue(tissue.toString());
			cell = row.createCell(1);
			cell.setCellValue(tissue.getChcID());
			cell = row.createCell(2);
			cell.setCellValue(tissue.getTissueTypeID());
			cell = row.createCell(3);
			if (!tissue.isMasterTissue())
				cell.setCellValue(tissue.getMasterTissue().toString());
			else
				cell.setCellValue("--------");
			int j = 4;

			for (String eavVarName : eavVariables.keySet()) {
				String modality = "";
				if (tissue.getEavData().get(eavVarName) != null
					&& tissue.getEavData().get(eavVarName).getModality() != null)
					modality = tissue.getEavData().get(eavVarName).getModality();
				else
					modality = "";
				cell = row.createCell(j);
				cell.setCellValue(modality);
				j++;
			}

			if (this.showTissueQuantities) {
				cell = row.createCell(j);
				cell.setCellValue(tissue.getQuantityLeft() != null ? tissue.getQuantityLeft()
					: "");
			}

			n++;
		}
		FileOutputStream out = new FileOutputStream(excelFile);
		wb.write(out);
		out.close();
		return excelFile;
	}

}
